package com.megalith.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.megalith.constant.ResultCode;
import com.megalith.dto.ActivityRebackDTO;
import com.megalith.dto.ManagerVerifyDTO;
import com.megalith.dto.StaffApplyDTO;
import com.megalith.dto.StaffLeaveTicketDTO;
import com.megalith.service.HolidayService;
import com.megalith.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricDetail;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author lfp
 * @Date 2022/7/15
 * @Version 1.0
 */
@Slf4j
@Service
public class HolidayServiceImpl implements HolidayService {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;

    @Override
    public List<TaskEntityVO> queryActiveHolidayProcessTaskList() {
        //查询当前正在执行中的所有请假流程节点
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("holiday")
                .active()//已激活的任务
                .list();

        List<TaskEntityVO> taskEntityVOList = taskList.stream().map(task -> {
            return BeanUtil.copyProperties(task, TaskEntityVO.class);
        }).collect(Collectors.toList());
        return taskEntityVOList;
    }

    @Override
    public String startHolidayProcess(StaffApplyDTO applyDTO) {
        Map<String,Object> param = new HashMap<>();
        param.put("staff",applyDTO.getName());//员工
        param.put("manager",applyDTO.getManager());//部门经理
        param.put("generalManager",applyDTO.getGeneralManager());//总经理
        param.put("humanResources",applyDTO.getHumanResources());//人力资源

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", "order_id_20250102", param);

        //ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday",param);
        return processInstance.getId();
    }

    @Override
    public Result fillHolidayTicket(StaffLeaveTicketDTO leaveTicketDTO) {
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("holiday")
                .active()
                .taskAssignee(leaveTicketDTO.getName())//根据员姓名查询待处理任务
                .singleResult();

        Map<String,Object> param = new HashMap<>();
        param.put("days",leaveTicketDTO.getDays());//请假天数。
        param.put("reason",leaveTicketDTO.getReason());//请假原因

        if(task != null){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),leaveTicketDTO.getReason());
            taskService.complete(task.getId(),param);
            return Result.ok(task.getId(), ResultCode.SYS_SUCCESS.getDes());
        }else {
            return Result.error(ResultCode.SYS_ERROR);
        }
    }

    @Override
    public Result managerVerifyHolidayTask(ManagerVerifyDTO managerVerifyDTO) {
        Map<String,Object> param = new HashMap<>();
        param.put("opinion",managerVerifyDTO.getOpinion());//审批意见

        Task task = taskService.createTaskQuery()
                .processDefinitionKey("holiday")
                .active()
                .taskAssignee(managerVerifyDTO.getManagerName())//根据经理名字，查询待办任务
                .singleResult();

        if(task != null){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),managerVerifyDTO.getOpinion());
            taskService.complete(task.getId(),param);
            log.info("{},完成了:{}任务",managerVerifyDTO.getManagerName(),task.getName());
            return Result.ok(task.getId(),ResultCode.TASK_SUCCESS.getDes());
        }else {
            return Result.sysError(ResultCode.TASK_NOT_FOUND.getCode(),ResultCode.TASK_NOT_FOUND.getDes());
        }
    }

    @Override
    public void processActivityReback(ActivityRebackDTO rebackDTO) {
        //根据流程实例ID，将当前请假流程，退回到指定节点
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(rebackDTO.getProcessInstanceId())
                .moveActivityIdTo(rebackDTO.getCurrentActivityId(),rebackDTO.getNewActivityId())
                .changeState();
    }

    @Override
    public List<HistoricTaskInstanceVO> queryHistoricTaskInfoList(String processInstanceId) {
        //查找历史任务信息
        List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)//流程实例编号
                .processFinished()//仅选择作为已完成流程实例的历史任务实例。未结束的流程无法查询
                .orderByHistoricTaskInstanceEndTime()
                .asc()
                .list();

        List<HistoricTaskInstanceVO> historicTaskInstanceVOList = historicTaskInstanceList.stream().map(task -> {
            HistoricTaskInstanceVO historicTaskInstanceVO = BeanUtil.copyProperties(task, HistoricTaskInstanceVO.class);

            historicTaskInstanceVO.setStartTime(DateUtil.formatDateTime(task.getStartTime()))
                    .setEndTime(DateUtil.formatDateTime(task.getEndTime()));

            return historicTaskInstanceVO;
        }).collect(Collectors.toList());

        return historicTaskInstanceVOList;
    }

    @Override
    public List<HistoricActivityInstanceEntityVO> queryHistoricActivityInfoList(String processInstanceId) {
        //历史活动信息
        List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime()
                .finished()//仅查询已处理（完成）的活动
                .asc()
                .list();

        List<HistoricActivityInstanceEntityVO> historicActivityInstanceEntityVOList = historicActivityInstanceList.stream().map(activity -> {
            //历史活动基本属性拷贝
            HistoricActivityInstanceEntityVO historicActivityInstanceEntityVO = BeanUtil.copyProperties(activity, HistoricActivityInstanceEntityVO.class);

            historicActivityInstanceEntityVO.setStartTime(DateUtil.formatDateTime(activity.getStartTime()))
                    .setEndTime(DateUtil.formatDateTime(activity.getEndTime()));

            //查询活动相关流程变量
            List<HistoricDetail> historicDetailList = historyService.createHistoricDetailQuery()
                    .processInstanceId(activity.getProcessInstanceId())
                    .activityInstanceId(activity.getId())
                    .list();
            if (historicDetailList.size() > 0) {
                List<HistoricDetailVariableInstanceVO> variableList = new ArrayList();
                for (HistoricDetail historicDetail : historicDetailList) {
                    variableList.add(BeanUtil.copyProperties(historicDetail, HistoricDetailVariableInstanceVO.class));
                }
                //设置活动相关流程变量
                historicActivityInstanceEntityVO.setVariableList(variableList);
            }

            return historicActivityInstanceEntityVO;
        }).collect(Collectors.toList());

        return historicActivityInstanceEntityVOList;
    }
}
